import { Socket } from "dgram";
import Constants from "../libs/Constants";
import { GameEvent } from "../libs/GameEvent";
import Helper from "../libs/HelperMgr";
import CameraManager from "./CameraManager";
import GameManager from "./GameManager";

const { ccclass, property } = cc._decorator;

@ccclass
export default class JoystickRight extends cc.Component {


  private player: cc.Node = null;



  @property({
    type: cc.Node,
    displayName: 'Dot',
    tooltip: '摇杆操纵点',
  })
  dot: cc.Node = null;

  @property({
    type: cc.Node,
    displayName: 'Ring',
    tooltip: '摇杆背景节点',
  })
  ring: cc.Node = null;

  @property({
    type: cc.Node,
    displayName: 'Over',
    tooltip: '放弃节点',
  })
  over: cc.Node = null;

  @property({
    type: cc.Label,
    displayName: 'force',
    tooltip: '摇杆力的大小',
  })
  force: cc.Label = null;



  @property({
    tooltip: 'curDir',
  })
  curDir = ""

  @property({
    tooltip: 'faceTo',
  })
  faceTo = "K"

  @property({
    displayName: 'Move Dir',
    tooltip: '移动方向',
  })
  moveDir: cc.Vec2 = new cc.Vec2(0, 1);

  _speedType = Constants.SpeedType.STOP;

  @property({
    type: cc.Integer,
    tooltip: '停止时速度',
  })
  stopSpeed = 0;

  @property({
    type: cc.Integer,
    tooltip: '正常速度',
  })
  normalSpeed = 200;

  @property({
    type: cc.Integer,
    tooltip: '最快速度',
  })
  fastSpeed = 200;

  @property({
    type: cc.Enum(Constants.JoystickType),
    displayName: 'joystickType',
    tooltip: 'Touch Type',
  })
  joystickType = Constants.JoystickType.FOLLOW;


  @property({
    tooltip: '摇杆所在位置',
  })
  _stickPos = null;

  @property({
    tooltip: '触摸位置',
  })
  _touchLocation = null;

  _radius = null;

  // from self
  _moveSpeed: number = 0;
  _movePosi: cc.Vec2 = null;
  _force: number = 0;

  _giveup: boolean = false;



  //playe getPosition
  playerPos: cc.Vec2 = null;


  beginDotPos: cc.Vec2 = null;
  endDotPos: cc.Vec2 = null;

  onLoad() {
    this.player = GameManager.instace.player;
    this._radius = this.ring.width / 2;
    this._initTouchEvent();
    if (this.joystickType === Constants.JoystickType.FOLLOW) {
      this.node.opacity = 0;
    }
  }



  _initTouchEvent() {
    this.node.on(cc.Node.EventType.TOUCH_START, this._touchStartEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_END, this._touchEndEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);

  }

  _touchStartEvent(event) {
    const touchPos = this.node.convertToNodeSpaceAR(event.getLocation());

    if (this.joystickType === Constants.JoystickType.FIXED) {
      this._stickPos = this.ring.getPosition();

      // 触摸点与圆圈中心的距离
      const distance = touchPos.sub(this.ring.getPosition()).mag();

      // 手指在圆圈内触摸,控杆跟随触摸点
      this._radius > distance && this.dot.setPosition(touchPos);

    } else if (this.joystickType === Constants.JoystickType.FOLLOW) {

      // 记录摇杆位置，给 touch move 使用
      this._stickPos = touchPos;
      this.node.opacity = 255;
      this._touchLocation = event.getLocation();

      // 更改摇杆的位置
      this.ring.setPosition(touchPos);
      // this.over.setPosition(touchPos.x + 150, touchPos.y + 100)
      this.dot.setPosition(touchPos);
      this.beginDotPos = touchPos;

    }
    this._isMove = true;

  }

  _touchMoveEvent(event) {
    // 如果 touch start 位置和 touch move 相同，禁止移动
    if (this.joystickType === Constants.JoystickType.FOLLOW && this._touchLocation === event.getLocation()) {
      return false;
    }

    // 以放弃圆圈为锚点获取触摸坐标
    const touchPos1 = this.over.convertToNodeSpaceAR(event.getLocation());
    const distance1 = touchPos1.mag();
    this._giveup = distance1 <= 30;

    // 以圆圈为锚点获取触摸坐标
    const touchPos2 = this.ring.convertToNodeSpaceAR(event.getLocation());
    const distance2 = touchPos2.mag();

    // 由于摇杆的 postion 是以父节点为锚点，所以定位要加上 touch start 时的位置
    const posX = this._stickPos.x + touchPos2.x;
    const posY = this._stickPos.y + touchPos2.y;

    // 归一化
    const p = cc.v2(posX, posY).sub(this.ring.getPosition()).normalize();

    let speedType;

    if (p.y > 0) {
      p.y = 0
    }

    if (this._radius > distance2) {
      this.dot.setPosition(cc.v2(posX, posY));
      speedType = Constants.SpeedType.NORMAL;
    } else {
      // 控杆永远保持在圈内，并在圈内跟随触摸更新角度
      const x = this._stickPos.x + p.x * this._radius;
      const y = this._stickPos.y + p.y * this._radius;
      this.dot.setPosition(cc.v2(x, y));
      this.endDotPos = cc.v2(x, y);

      speedType = Constants.SpeedType.FAST;
    }

    this.onTouchMove(event, { speedType: speedType, moveDistance: p })
  }

  _touchEndEvent(event) {
    this.dot.setPosition(this.ring.getPosition());
    if (this.joystickType === Constants.JoystickType.FOLLOW) {
      this.node.opacity = 0;
    }

    this.onTouchEnd(event, { speedType: Constants.SpeedType.STOP })
    this._isMove = false;
  }





  onTouchMove(event, data) {
    // if (DataMgr.meetUser) return;
    this._speedType = data.speedType;
    this.moveDir = data.moveDistance;
    this.setDir(data.moveDistance.x)
    if (this.beginDotPos && this.endDotPos) {
      if (GameManager.instace.playerIsStosh) {
        let offset = new cc.Vec2(this.endDotPos.x - this.beginDotPos.x, this.endDotPos.y - this.beginDotPos.y);
        GameEvent.emit(Constants.StageEvent.DrawParabola, offset)
      } else {
        GameEvent.emit(Constants.StageEvent.RotateRod, Helper.getAngele(this.endDotPos.x, this.endDotPos.y, this.beginDotPos.x, this.beginDotPos.y))
      }
    }

  }

  //设置朝向
  setDir(dir) {
    let scale = this.player.scaleY;
    this.player.scaleX = dir > 0 ? scale : -scale;
  }

  private _isMove: boolean = false;

  update(dt: number) {

    switch (this._speedType) {
      case Constants.SpeedType.STOP:
        this._moveSpeed = this.stopSpeed;
        break;
      case Constants.SpeedType.NORMAL:
        this._moveSpeed = this.normalSpeed;
        break;
      case Constants.SpeedType.FAST:
        this._moveSpeed = this.fastSpeed;
        break;
      default:
        break;
    }

    if (this._isMove) {
      if(!this._giveup){
        this._force += 0.5;
      }
      if (this._force > 100) {
        this._force = 100;
      }
      if (this.force) {
        this.force.string = this._giveup ? "放弃" : Math.round(this._force) + "%";
      }
    } else {
      this._force = 0;
    }
  }


  onTouchEnd(event, data) {
    if (GameManager.instace.playerIsStosh) {
      GameEvent.emit(Constants.StageEvent.ClearParabola)
    }
    if (this._giveup) {
      GameEvent.emit(Constants.StageEvent.ResetRod)
      return;
    }
    this._speedType = data.speedType;
    if (this.beginDotPos && this.endDotPos) {
      GameManager.instace.forcePercent = this._force;
      if (GameManager.instace.playerIsStosh) {
        GameEvent.emit(Constants.StageEvent.CastStosh)
      } else {
        GameEvent.emit(Constants.StageEvent.LaunchRod)
      }

    }
  }



}
